home *** CD-ROM | disk | FTP | other *** search
/ El Mac 9 / El Mac 9.iso / Shareware / Demos / Igor Demo Pro / 1 PutContentsIn Igor Pro Folder / WaveMetrics Procedures / Graphing / Wave Review Chart < prev   
Encoding:
Text File  |  1996-01-29  |  10.9 KB  |  391 lines  |  [TEXT/IGR0]

  1.  
  2. // ********* Wave Review Chart ***********
  3. //
  4. //    This package creates a control panel containing a strip-chart that can
  5. //    be connected to a binary wave file (or to a normal FIFO file).
  6. //    To use, run the CreateFileReviewChart() macro to create the chart panel,
  7. //    select an appropriate path from the popup menu,  click the
  8. //    open button and find a .bwav or FIFO file. 
  9. //
  10. //    You can also view a wave resident in memory by choosing _In Memory_ from the
  11. //    Path popup menu. This will require double the memory as for the wave by itself.
  12. //
  13. //    If the wave is very large, you can use the utility macro, SaveWaveFile(),
  14. //    to create a disk file from one of your waves in an experiment.
  15. //
  16. //    See the Wave Review Chart Demo experiment file for more info.
  17.  
  18. #pragma rtGlobals=1        // Use modern global access method.
  19.  
  20. #include <Keyword-Value>
  21.  
  22. Macro CreateFileReviewChart()
  23.     Make/O DataSamp=x            // a wave to put chanel 0 into when the => wave button is pressed
  24.     WM_WFGraph()
  25.     WM_WFPanel()
  26. End
  27.  
  28. Macro  SaveWaveFile(path,wname,fname)
  29.     String path
  30.     Prompt path,"place to write file", popup PathList("*",";","")
  31.     String wname
  32.     Prompt wname,"wave to write",popup WaveList("*",";","")
  33.     String fname="temp file.bwav"
  34.     
  35.     Save/O/C/P=$path $wname as fname
  36. End
  37.     
  38.  
  39. // This routine extracts info from a binary wave file (.bwav).
  40. // It uses magic numbers (offsets into the file) that you (the user) are not
  41. // expected to understand. You should use this routine only as a black box and you probably
  42. // should not attempt to change it.
  43. // On the other hand, you can use it as an example of a function using a temporary data
  44. // folder filled with variables as a way of returning more than one value.
  45. // 
  46. Function/S ExamineBinaryWaveFile(refnum)
  47.     Variable refnum
  48.     
  49.     FSetPos refnum,0
  50.     Variable binvers
  51.     FBinRead/F=2 refnum,binvers    // binary file version is short at offset 0
  52.     Variable v1,wfmType,wfmOffset,wfmPnts
  53.     Variable fsValid,topFullScale,botFullScale,wdeltaT
  54.     Variable headersize
  55.     String wName
  56.     do
  57.         if( binvers == 5 )
  58.             headersize= (2*2+4*4+2*4*4+3*4)        // from BinHeader
  59.             FSetPos refnum,headersize+26
  60.             FBinRead/F=2 refnum,v1                        // whVersion
  61.             if( v1 != 1 )
  62.                 return "unsupported wave header version"
  63.             endif
  64.             wName= PadString("",32,0)
  65.             FBinRead refnum,wName                        // bname
  66.             wfmOffset= 3*4                                // next thru modDate
  67.             FSetPos refnum,headersize+wfmOffset
  68.             FBinRead/F=3 refnum,wfmPnts                    // npnts
  69.             FBinRead/F=2 refnum,wfmType                    // type
  70.             wfmOffset += 2*4+8+32+8+4*4                // npnts thru nDim[MAXDIMS]
  71.             FSetPos refnum,headersize+wfmOffset
  72.             FBinRead/F=5 refnum,wdeltaT                    // sfA[0]
  73.             wfmOffset += 2*8*4+4+4*4                    // sfA thru dimUnits
  74.             FSetPos refnum,headersize+wfmOffset
  75.             FBinRead/F=2 refnum,fsValid                    // fsValid
  76.             wfmOffset +=4
  77.             FSetPos refnum,headersize+wfmOffset
  78.             FBinRead/F=5 refnum,topFullScale                // topFullScale
  79.             FBinRead/F=5 refnum,botFullScale                // botFullScale
  80.             wfmOffset += 2*8
  81.             wfmOffset += 4+4*4+4*4+4+16*4            // dataEUnits thru whUnused
  82.             wfmOffset += 4*2+5*4                        //  aModified thru sIndicies
  83.             break
  84.         endif
  85.         if( binvers == 2 )
  86.             headersize= (2+3*4+2)                    // from BinHeader2
  87.             FSetPos refnum,headersize+26
  88.             FBinRead/F=2 refnum,v1                        // whVersion
  89.             if( v1 != 0 )
  90.                 return "unsupported wave header version"
  91.             endif
  92.             wfmOffset= 0
  93.             FSetPos refnum,headersize+wfmOffset
  94.             FBinRead/F=2 refnum,wfmType                    // type
  95.             wfmOffset += 2+4                                // type thru next
  96.             wName= PadString("",20,0)
  97.             FBinRead refnum,wName                        // bname
  98.             wfmOffset += 20+2*2+4+2*4                    // bname thru xUnits
  99.             FSetPos refnum,headersize+wfmOffset
  100.             FBinRead/F=3 refnum,wfmPnts                    // npnts
  101.             wfmOffset += 4+2                                // npnts thru aModified
  102.             FSetPos refnum,headersize+wfmOffset
  103.             FBinRead/F=5 refnum,wdeltaT                    // hsA
  104.             wfmOffset += 2*8+2*2                        // hsA thru swModified
  105.             FSetPos refnum,headersize+wfmOffset
  106.             FBinRead/F=2 refnum,fsValid                    // fsValid
  107.             FBinRead/F=5 refnum,topFullScale                // topFullScale
  108.             FBinRead/F=5 refnum,botFullScale                // botFullScale
  109.             wfmOffset += 2+2*8+2+3*4+2+2*4            // useBits thru userComment
  110.             break
  111.         endif
  112.         return "not a supported binary file"
  113.     while(0)
  114.     NewDataFolder/S/O ebwresults
  115.     Variable/G offset= headersize+wfmOffset
  116.     Variable/G type= wfmType
  117.     Variable/G npnts= wfmPnts
  118.     String/G name= wName
  119.     if( !fsValid )
  120.         Make/N=(min(10000,wfmPnts)) ebwTmp
  121.         FSetPos refnum,headersize+wfmOffset
  122.         FBinRead/Y=(wfmType) refnum,ebwTmp
  123.         WaveStats/Q ebwTmp
  124.         topFullScale= V_Max
  125.         botFullScale= V_Min
  126.         KillWaves ebwTmp
  127.     endif
  128.     Variable/G topFS= topFullScale
  129.     Variable/G botFS= botFullScale
  130.     Variable/G deltaT= wdeltaT
  131.     SetDataFolder ::
  132.     return ""
  133. end
  134.  
  135. // This could be a built-in function some day so we try to avoid name conflits.
  136. Function WM_NumSize(ntype)
  137.     Variable ntype
  138.     
  139.     Variable isCmplx= (ntype%&1) != 0,nbytes= 0
  140.     ntype= ntype%&(2+4+8+16+32)
  141.     if( ntype==0 )
  142.         return 1                // text, 1 byte, can't be complex
  143.     endif
  144.     do
  145.         if( ntype==2 )
  146.             nbytes= 4                // float
  147.             break
  148.         endif
  149.         if( ntype==4 )
  150.             nbytes= 8                // double
  151.             break
  152.         endif
  153.         if( ntype==8 )
  154.             nbytes= 1                // byte
  155.             break
  156.         endif
  157.         if( ntype==16 )
  158.             nbytes= 2                // short
  159.             break
  160.         endif
  161.         if( ntype==32 )
  162.             nbytes= 4                // long
  163.             break
  164.         endif
  165.     while(0)
  166.     if( isCmplx )
  167.         return nbytes*2
  168.     else
  169.         return nbytes
  170.     endif
  171. end
  172.  
  173. Proc WM_WFGetWave(wname)
  174.     String wname
  175.     Prompt wname,"wave to review",popup WaveList("*",";","")
  176.     
  177.     NewDataFolder/O ebwresults
  178.     String/G :ebwresults:name= wname
  179. end
  180.  
  181.  
  182. Function WM_WFLoadFifoFromWave()
  183.     Execute "WM_WFGetWave()"
  184.     String wname= StrVarOrDefault(":ebwresults:name","")
  185.     if( DataFolderExists("ebwresults") )
  186.         KillDataFolder ebwresults
  187.     endif
  188.     Wave w= $wname
  189.     if( WaveExists(w) == 0 )
  190.         return 0
  191.     endif
  192.  
  193.     Variable npts= numpnts(w),i
  194.  
  195.     WaveStats/Q/R=[0,10000] w
  196.  
  197.     NewFIFOChan/Y=(WaveType(w)) dave, $NameOfWave(w), 0, 1, V_Min, V_Max, ""
  198.     CtrlFIFO dave,size=npts,deltaT= deltax(w),start
  199.     
  200.     i= 0
  201.     do
  202.         AddFIFOData dave,w[i]
  203.         i+=1
  204.     while(i<npts)
  205.     CtrlFIFO dave,stop
  206.     
  207.     DoUpdate        // let the chart recognize the new fifo and autoconfigure
  208.     Chart davechart,oMode= 1,ppStrip= 1        // need to set ppStrip because autoconfigure may set it assuming we will be acually taking live data (depends of deltaT)
  209.     Chart davechart,jumpTo=300
  210.     Chart davechart,title="data from wave"+NameOfWave(w)
  211.     return 1
  212. end
  213.  
  214.  Function WM_WFDoStartButton()
  215.     FIFOStatus/Q dave
  216.     if( V_FLag!=0 )
  217.         KillFIFO dave
  218.         DoUpdate                // let chart know we killed its fifo
  219.     endif
  220.     NewFIFO dave
  221.  
  222.     variable refnum
  223.     
  224.     ControlInfo pathPop
  225.     if( CmpStr(S_value,"_current_") == 0 )
  226.         Open/R/T="????"/D/M="select a FIFO file or wave" refnum
  227.     else
  228.         if( CmpStr(S_value,"_In Memory_") == 0 )
  229.             return WM_WFLoadFifoFromWave()            // ********** exit if use resident wave
  230.         else
  231.             Open/P=$S_value/R/T="????"/D/M="select a FIFO file or wave" refnum
  232.         endif
  233.     endif
  234.     if( strlen(S_FileName) == 0 )
  235.         return 0
  236.     endif
  237.     String fName= S_FileName
  238.  
  239.     String s= PadString("",8,0)
  240.     Open/R refnum as fName
  241.  
  242.     FStatus refnum
  243.     Chart davechart,title="data from "+S_FileName
  244.     
  245.     FBinRead refnum,s
  246.     FSetPos refnum,0
  247.     if( CmpStr(s,"IGORfifo") == 0 )
  248.         CtrlFIFO dave,rfile=refnum
  249.     else
  250.         String err= ExamineBinaryWaveFile(refnum)
  251.         if( strlen(err) == 0 )
  252.             Variable offset= NumVarOrDefault(":ebwresults:offset",-1)
  253.             Variable type= NumVarOrDefault(":ebwresults:type",-1)
  254.             String wname= StrVarOrDefault(":ebwresults:name","dummy")
  255.             Variable topFS= NumVarOrDefault(":ebwresults:topFS",1)
  256.             Variable botFS= NumVarOrDefault(":ebwresults:botFS",-1)
  257.             Variable npnts= NumVarOrDefault(":ebwresults:npnts",0)
  258.             Variable deltaT= NumVarOrDefault(":ebwresults:deltaT",1)
  259.             KillDataFolder ebwresults
  260.             NewFIFOChan/Y=(type) dave, $wname, 0, 1, botFS, topFS, ""
  261.             CtrlFIFO dave,deltaT= deltaT
  262.             CtrlFIFO dave,rdfile=refnum,doffset=offset,dsize=npnts*WM_NumSize(type)
  263.             DoUpdate        // let the chart recognize the new fifo and autoconfigure
  264.             Chart davechart,oMode= 1
  265.             Chart davechart,jumpTo=300
  266.             ControlInfo stylePop
  267.             Chart davechart,lineMode(0)= V_Value-1
  268.             if( deltaT < 0.05 )
  269.                 DoUpdate        
  270.                 Chart davechart,ppStrip= 1        // need to set ppStrip because autoconfigure may set it assuming we will be acually taking live data (depends of deltaT)
  271.             endif
  272.         else
  273.             DoAlert 0,err
  274.             Close refnum
  275.             return 0
  276.         endif
  277.     endif
  278.     return 1
  279. end
  280.  
  281.     
  282.     
  283. Function StartStopButton(theTag) : ButtonControl
  284.     String theTag
  285.     
  286.     if( cmpstr(theTag,"bStart") == 0 )
  287.         if( WM_WFDoStartButton() )
  288.             Button $theTag,title="Close",rename=bStop
  289.         endif
  290.     else
  291.         Button $theTag,title="Open...",rename=bStart
  292.         KillFIFO dave
  293.         Chart davechart,title="no data"
  294.     endif
  295. End
  296.  
  297.  
  298.  
  299.  
  300.  
  301. Function WM_WFExpandProc(ctrlName) : ButtonControl
  302.     String ctrlName
  303.  
  304.     ControlInfo davechart
  305.     Variable newPPS= NumByKey("PPSTRIP",S_Value)
  306.     if( StrSearch(ctrlName,"up",0) >= 0 )
  307.         newPPS *= 2
  308.     else
  309.         newPPS /= 2
  310.     endif
  311.     newPPS= limit(newPPS,1,32)
  312.     Chart davechart,ppStrip= newPPS
  313. End
  314.  
  315.  
  316. Function WM_WFFifoToWave(ctrlName) : ButtonControl
  317.     String ctrlName
  318.     
  319.     if( WM_WFCheckInvalid() )
  320.         return 0
  321.     endif
  322.  
  323.     ControlInfo davechart
  324.     String chan= StrByKey("NAME0",S_Value)
  325.     FIFO2Wave/S=3/R=[NumByKey("LHSAMP",S_Value),NumByKey("RHSAMP",S_Value)] dave,$chan,DataSamp
  326. End
  327.  
  328. Function WM_WFStyleProc(ctrlName,popNum,popStr) : PopupMenuControl
  329.     String ctrlName
  330.     Variable popNum
  331.     String popStr
  332.  
  333.     Chart davechart,lineMode(0)= popNum-1
  334. End
  335.  
  336. Function WM_WFCheckInvalid()
  337.     FIFOStatus/Q dave
  338.     if( V_Flag==0 )
  339.         return 1
  340.     endif
  341.     return NumByKey("VALID",S_Info)==0
  342. end
  343.  
  344. Function WM_WFAutoscaleBProc(ctrlName) : ButtonControl
  345.     String ctrlName
  346.     
  347.     if( WM_WFCheckInvalid() )
  348.         return 0
  349.     endif
  350.  
  351.     ControlInfo davechart
  352.     String chan= StrByKey("NAME0",S_Value)
  353.     Make/O astemp
  354.     FIFO2Wave/S=3/R=[NumByKey("LHSAMP",S_Value),NumByKey("RHSAMP",S_Value)] dave,$chan,astemp
  355.     WaveStats/Q astemp
  356.     KillWaves astemp
  357.  
  358.     FIFOStatus/Q dave
  359.     Variable plusFS= NumByKey("FSPLUS0",S_Info)
  360.     Variable minusFS= NumByKey("FSMINUS0",S_Info)
  361.     chart davechart,offset(0)= (V_min+V_max)/2 - (plusFS+minusFS)/2
  362.     chart davechart,gain(0)=(plusFS-minusFS)/(V_max-V_min)
  363. End
  364.  
  365. Proc WM_WFGraph()
  366.     PauseUpdate; Silent 1        | building window...
  367.     Display /W=(5,42,400,250) DataSamp
  368.     ModifyGraph grid(left)=1
  369.     ModifyGraph minor(left)=1
  370.     Label bottom "\\U"
  371. EndMacro
  372.  
  373. Proc WM_WFPanel()
  374.     PauseUpdate; Silent 1        | building window...
  375.     NewPanel /W=(184,59,550,364)
  376.     SetDrawLayer UserBack
  377.     SetDrawEnv fillfgc= (65535,54607,32768)
  378.     DrawRect 356,219,267,271
  379.     Chart davechart,pos={9,8},size={348,209},title="no data",fSize=9,fifo= dave
  380.     Chart davechart,chans={0},umode= 2
  381.     Button bStart,pos={10,223},size={50,20},proc=StartStopButton,title="Open..."
  382.     Button ToWaveButton,pos={168,277},size={130,20},proc=WM_WFFifoToWave,title="chart => graph"
  383.     Button upButton,pos={272,223},size={80,20},proc=WM_WFExpandProc,title="H Contract"
  384.     Button downButton,pos={272,247},size={80,20},proc=WM_WFExpandProc,title="H Expand"
  385.     PopupMenu stylePop,pos={163,249},size={97,19},proc=WM_WFStyleProc,title="Style:"
  386.     PopupMenu stylePop,mode=1,value= #"\"Dots;Lines;Fill\""
  387.     Button AutoButton,pos={168,220},size={74,20},proc=WM_WFAutoscaleBProc,title="Autoscale"
  388.     PopupMenu pathPop,pos={5,249},size={126,19},title="path"
  389.     PopupMenu pathPop,mode=1,value= #"\"_In Memory_;_current_;\"+PathList(\"*\", \";\", \"\")"
  390. EndMacro
  391.